package dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import domain.Tag;

public class TagDAO {

	@Autowired
	@Qualifier("jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	// private static EmbeddedDatabaseType edt = EmbeddedDatabaseType.DERBY;
	// private static EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
	// private static EmbeddedDatabase db = (EmbeddedDatabase) builder.setType(edt).addScript("schema.sql").build();

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	private static final String SELECT_ALL_TAGS_BY_TYPE_QUERY = "SELECT * FROM penguin.tag WHERE tag_type_id = ? ORDER BY counter DESC";
	private static final String SELECT_ALL_BY_TAG_QUERY = "SELECT * FROM penguin.tag WHERE tag = ? AND tag_type_id = ? AND file_name = ?";
	// private static final String INSERT_TAG_QUERY =
	// "INSERT INTO penguin.tag (tag,tag_type_id,last_search) VALUES (:tag,:tag_type_id,:last_search)";
	private static final String INSERT_TAG_QUERY = "INSERT INTO penguin.tag (tag,counter,tag_type_id,file_name) VALUES (?,?,?,?)";
	private static final String UPDATE_TAG_QUERY = "UPDATE penguin.tag SET counter = counter+1, last_search = ? WHERE tag = ?";

	public int insertTag(String tag, int counter, int tag_type_id,
			String file_name) {

		KeyHolder keyHolder = new GeneratedKeyHolder();

		// MapSqlParameterSource parameters = new MapSqlParameterSource();
		// parameters.addValue("tag", tag);
		// parameters.addValue("counter", counter);
		// parameters.addValue("tag_type_id", tag_type_id);
		// parameters.addValue("file_name", file_name);
		// parameters.addValue("last_search", last_search);

		try {
			// JdbcTemplate template = new JdbcTemplate(db);

			jdbcTemplate.update(INSERT_TAG_QUERY, new Object[] { tag, counter,
					tag_type_id, file_name }, new int[] { Types.VARCHAR,
					Types.INTEGER, Types.INTEGER, Types.VARCHAR });
			if (keyHolder.getKey() != null) {
				int id = keyHolder.getKey().intValue();
				// System.out.println("Tag Generated:"+ id);
				return id;
			}

		} catch (Throwable e) {
			e.printStackTrace();
		}
		return 0;

	}

	public int updateTag(int counter, Date last_search, String tag) {

		MapSqlParameterSource parameters = new MapSqlParameterSource();
		parameters.addValue("counter", counter);
		parameters.addValue("last_search", last_search);
		try {
			// JdbcTemplate template = new JdbcTemplate(db);

			int noOfRowsUpdated = jdbcTemplate.update(UPDATE_TAG_QUERY,
					new Object[] { last_search, tag }, new int[] {
							Types.TIMESTAMP, Types.VARCHAR });

			if (noOfRowsUpdated != 0) {
				// System.out.println("Tags Updated:"+ noOfRowsUpdated);
				return noOfRowsUpdated;
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return 0;
	}

	 public List<Tag> selectAllByType(int tag_type_id){
	
		 List<Tag> tags = this.jdbcTemplate.query(SELECT_ALL_TAGS_BY_TYPE_QUERY,
					new Object[] { tag_type_id},
					new TagRowMapper());
	
		 return tags;
	 }

	class TagRowMapper implements RowMapper<Tag> {
		public Tag mapRow(ResultSet rs, int rowNum) throws SQLException {
			Tag myTag = new Tag();
			myTag.setId(rs.getInt("id"));
			myTag.setTag(rs.getString("tag"));
			myTag.setCounter(rs.getInt("counter"));
			myTag.setTag_type_id(rs.getInt("tag_type_id"));
			myTag.setLast_search(rs.getTimestamp("last_search"));
			myTag.setFile_name(rs.getString("file_name"));
			return myTag;
		}
	}

	// PROCESS OF POPULATING THE DB WITH PARSED TAGS/WORDS
	public Boolean tagProcessing(final String tag, final int tag_type_id,
			final String file_name) {
		try {
			List<Tag> tags = this.jdbcTemplate.query(SELECT_ALL_BY_TAG_QUERY,
					new Object[] { tag, tag_type_id, file_name },
					new TagRowMapper());

			if (tags.isEmpty()) {
				// System.out.println("Tag does not exist in DB - Insert Record");
				java.util.Date utilDate = new java.util.Date();
				java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
				int x = insertTag(tag, 1, tag_type_id, file_name);
				return true;
			}

			if ((tags.size() != 0) && (tags.size() == 1) && (tags != null)) {
				// System.out.println("Tag Already in DB - Update Record");
				int cnt = 0;
				// Tag elements which remain the same
				for (Tag tagArray : tags) {
					cnt = tagArray.getCounter() + 1;
				}
				java.util.Date utilDate = new java.util.Date();
				java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
				// tagObj.setLast_search(sqlDate);

				// Tag is updated
				updateTag(cnt, sqlDate, tag);
				return true;
			}
		} catch (Throwable e) {
			e.printStackTrace();
			return false;
		}
		return false;
	}

	// PROCESS OF SETTING WEIGHTS TO EACH TAG IN A SPECIFIC CATEGORY/TYPE
	// public Map<Tag,Float> getWeights(int tag_type_id){
	//
	// Map<Tag,Float> weights = new HashMap<Tag,Float>();
	//
	// List<Tag> tags = selectAllByType(tag_type_id);
	// int maxCount = 0;
	//
	// //get the maximum count
	// for (Tag tag: tags) {
	// if(tag.getCounter()>maxCount){
	// maxCount = tag.getCounter();
	// }
	// }
	//
	// for (Tag tag: tags) {
	// int count = tag.getCounter();
	// float percent = ((count/maxCount)*100);
	// weights.put(tag,percent);
	// }
	//
	// return null;
	// }

	public void loop(String word) {
		System.out.print(word);
	}

	public static void main(String a[]) {
		try {
			ApplicationContext appContext = new FileSystemXmlApplicationContext(
					"src/main/java/resources/applicationContext.xml");
			TagDAO dao = (TagDAO) appContext.getBean("tagDao");
			// ApplicationContext appContext = new
			// ClassPathXmlApplicationContext("classpath:applicationContext.xml");
			String[] WORDS = { "art", "art", "baby" };
			// ApplicationContext appContext = new
			// FileSystemXmlApplicationContext("src/main/java/resources/applicationContext.xml");
			// TagDAO dao = (TagDAO) appContext.getBean("tagDao");
			// TagDAO dao = new TagDAO();
			// INSERT PARSED TAGS
			for (String w : WORDS) {
				// dao.loop(w);
				dao.tagProcessing(w, 1, "test");
			}
			// GET TAGS AND WEIGHTS
			// Map<Tag,Float> tags = dao.getWeights(1);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
